package UsedCar;

import java.awt.Color;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.ahmadsoft.arrays.FasterArrayList;

import uchicago.src.sim.space.Object2DTorus;

/**
 * @author August F.Y. Chao
 * 
 */
public class Seller extends Agent {
	/**
	 * @param AVG_CHARGE_RATIO
	 *            車價加多少成
	 */
	protected double AVG_CHARGE_RATIO = 0.2;
	/**
	 * @param service_ratio
	 *            實際的加價
	 */
	protected double service_ratio = 0;
	/**
	 * @param TYPE_ALTRUISM
	 *            利他型 0
	 * @param TYPE_ONLY_ADV
	 *            純廣告型 1
	 * @param TYPE_ONLY_B
	 *            分享基本知識 2
	 */
	public static final int TYPE_ALTRUISM = 0, TYPE_ONLY_ADV = 1,
			TYPE_ONLY_B = 2, TYPE_SHARE_ERR = 3;
	/**
	 * @param role
	 *            角色
	 */
	protected String role = "S";

	/**
	 * @param type
	 *            經營策略
	 */
	protected int type;
	/**
	 * @param SUGGEST_CAR_MAX
	 *            推給買家的車型數量
	 */
	protected int SUGGEST_CAR_MAX = 1;
	/**
	 * @param total_surplus_value
	 *            總營收
	 */
	protected int total_surplus_value = 0;

	/**
	 * @param soldCarL
	 *            賣掉的車子
	 * @param trashCarL
	 *            賣不掉的車子
	 */
	protected FasterArrayList<Car> soldCarL = new FasterArrayList<Car>(),
			trashCarL = new FasterArrayList<Car>();

	/**
	 * @param space
	 *            交易平台
	 * @param knows
	 *            知識市場
	 * @param frm
	 *            知識庫存
	 * @param knowR
	 *            開始的知識比例
	 * @param qual
	 *            車子的品質模式
	 * @param eval
	 *            估價的 0 樂觀、1 悲觀、2 平平
	 * @param isInfluence
	 *            是否進行影響計算
	 * @param type
	 *            經營策略準則
	 */
	public Seller(Object2DTorus sellerS, Object2DTorus space, Forum frm,
			Knowledges knows, Quality qual, boolean isInfluence, float knowR,
			int eval, int type) {
		super(sellerS, space, frm, qual, knows, isInfluence, eval);
		this.setMyColor(Color.YELLOW);

		// setting knows variables
		this.setInitKnowR(0.8f);

		this.initKnows();

		// update seller place
		this.sellerS.putObjectAt(this.getMyX(), this.getMyY(), this);

		// 設定角色
		this.setRole("S");
		this.setType(type);

		// 設定參數
		this.setVariables();
	}

	/**
	 * 產生分享的文章
	 * 
	 * @param quality
	 *            文章品質
	 */
	public void sharePost(float quality) {
		float sharR = this.getKnowsShareR();
		String[] shareKnows = this.knowsM.getKnows(this.getMyknows(), sharR);

		Post art = new Post(this, shareKnows, quality, Post.POST_TYPE_ARTICLE);
		addInflu(art);

		add2Forum(art);
	}

	/**
	 * 分享基本知識的文章
	 * 
	 * @param quality
	 *            文章品質
	 */
	public void sharePostBasic(float quality) {
		float sharR = this.getKnowsShareR();
		String[] shareKnows = this.knowsM.getKnowsBasic(this.getMyknows(),
				sharR);
		Post art = new Post(this, shareKnows, quality, Post.POST_TYPE_ARTICLE);
		addInflu(art);

		add2Forum(art);
	}

	/**
	 * 只傳廣告
	 * 
	 * @param quality
	 *            文章品質
	 */
	public void sharePostAdv(float quality) {
		float sharR = this.getKnowsShareR();
		String[] shareKnows = this.knowsM.getKnows(this.getMyknows(), sharR);

		Post art = new Post(this, shareKnows, quality, Post.POST_TYPE_ARTICLE);
		addInflu(art);

		add2Forum(art);
	}

	// stop here
	/**
	 * @todo herer!!
	 * @param quality
	 */
	public void sharePostErr(float quality) {
		float sharR = this.getKnowsShareR();
		String[] shareKnows = this.knowsM.getKnows(this.getMyknows(), sharR);

		for (int idx = 0; idx < shareKnows.length; idx++) {

		}

		Post art = new Post(this, shareKnows, quality, Post.POST_TYPE_ARTICLE);
		addInflu(art);

		add2Forum(art);
	}

	/**
	 * 依參數決定是否加入影響值
	 * 
	 * @param p
	 *            a Post 物件
	 */
	public void addInflu(Post p) {
		if (isInflu) {
			p.addInflu(sellerString());
		}
	}

	/**
	 * @return 賣家的字串
	 */
	public String sellerString() {
		return getMyX() + "_" + getMyY();
	}

	/**
	 * 進行知識分享
	 */
	public void doSharing() {
		int postNum = maxPostNum;
		float quality = 1;
		switch (this.getType()) {
		// 如果是利他型的，就都分享
		case TYPE_ALTRUISM:
			for (int i = 0; i < postNum; i++) {
				this.sharePost(quality);
			}
			break;
		// 如果是只分享基本知識的
		case TYPE_ONLY_B:
			for (int i = 0; i < postNum; i++) {
				sharePostBasic(quality);
			}
			break;
		// 如果是只打廣告的
		case TYPE_ONLY_ADV:
			for (int i = 0; i < postNum; i++) {
				sharePostAdv(quality);
			}
			break;
		// 只分享錯誤的
		case TYPE_SHARE_ERR:
			for (int i = 0; i < postNum; i++) {
				sharePostErr(quality);
			}
		}
	}

	/**
	 * 賣掉一輛車
	 * 
	 * @param aCar
	 */
	public void sold(Car aCar, Buyer ber) {
		aCar.owner = ber;
		aCar.buyFrom = this;
		ber.carL.add(aCar);
		carL.remove(aCar);
		soldCarL.add(aCar);
		// 營收值
		total_surplus_value += aCar.getEvaledPrice() - evaluate(aCar);

		// 沒車子了
		if (carL.size() <= 0) {
			setMyColor(Color.BLACK);
		}
	}

	/**
	 * @return 取得經營字屬
	 */
	public String getRT() {
		switch (type) {
		case TYPE_ALTRUISM:
			return "A";
		case TYPE_ONLY_ADV:
			return "O";
		case TYPE_ONLY_B:
			return "B";
		}
		return null;
	}

	/**
	 * 請老闆給可以買的車子清單
	 * 
	 * @param ct
	 *            車型
	 * @param price
	 *            價 格
	 * 
	 * @return 符合的車子
	 */
	public List<Car> suggestCars(int ct, int price) {
		long time = System.currentTimeMillis();
		List<Car> rCar = new FasterArrayList<Car>();

		Set<Integer> prices = carLByPrice.keySet();
		Iterator<Integer> it = prices.iterator();
		while (it.hasNext() && rCar.size() <= SUGGEST_CAR_MAX) {
			// Get element
			int ele = it.next();

			if (ele <= price) {
				List<Car> cars = carLByPrice.get(ele);
				Iterator<Car> cit = cars.iterator();
				while (cit.hasNext()) {
					Car aCar = cit.next();
					if (aCar.getCarType() == ct) {
						rCar.add(aCar);
					}
				}
			}
		}
		if (FLAG) {
			time = System.currentTimeMillis() - time;
			if (time > 5)
				System.out.println("Seller::suggestCars(): " + time);
		}
		return rCar;
	}

	// ---------------------------------------------------------------------------------------------------------------------------------------------//
	// Over-Rides
	// ---------------------------------------------------------------------------------------------------------------------------------------------//
	@Override
	public void setVariables() {
		this.setMaxPostNum(10);
		this.maxReadNum = 5;

		// 服務費
		// Random.createNormal(AVG_CHARGE_RATIO, AVG_CHARGE_RATIO / 2);
		this.setService_ratio(AVG_CHARGE_RATIO);

	}

	public int evaulate(Car aCar) {
		float price = super.evaluate(aCar);
		return (int) (price * (1 + getService_ratio()));
	}

	@Override
	public void doKM() {
		doSharing();
		doReading();
	}

	/**
	 * 設定讀完後的行為
	 */
	public void doReadingAfterChg() {

		if (!this.imp.isNull()) {
			if (this.imp.getMaxKey() != this.sellerString()) {
				switch (this.person_Eval) {
				case Seller.PERSON_EVAL_OPTIMISM:
					this.person_Eval = Seller.PERSON_EVAL_NEUTRAL;
					System.out.println("CHG: + -> =");

					break;
				case Seller.PERSON_EVAL_NEUTRAL:
					this.person_Eval = Seller.PERSON_EVAL_PESSMISTIC;
					System.out.println("CHG: = -> -");
					break;
				case Seller.PERSON_EVAL_PESSMISTIC:
					this.person_Eval = Seller.PERSON_EVAL_PESSMISTIC;
					break;
				}
			} else {
				switch (this.person_Eval) {
				case Seller.PERSON_EVAL_OPTIMISM:
					this.person_Eval = Seller.PERSON_EVAL_OPTIMISM;
					break;
				case Seller.PERSON_EVAL_NEUTRAL:
					this.person_Eval = Seller.PERSON_EVAL_OPTIMISM;
					System.out.println("CHG: = -> +");
					break;
				case Seller.PERSON_EVAL_PESSMISTIC:
					this.person_Eval = Seller.PERSON_EVAL_NEUTRAL;
					System.out.println("CHG - -> =");
					break;
				}
			}
		}
	}

	public void doReading() {
		List<Post> posts = this.frm.getReadPosts(maxReadNum);
		if (posts.size() > 0) {
			Iterator<Post> itr = posts.iterator();
			while (itr.hasNext()) {
				Post p = itr.next();
				
				if (p.getOwner().getRole() == "B") {
					System.out.println("Frm=" + p.influV);
					this.imp.addImp(p.influSeller, p.influV);
				}
			}
		}
		// doReadingAfterChg();
	}

	public int getType() {
		return type;
	}

	public void setType(int type) {
		this.type = type;
	}

	/**
	 * 變老，且移掉沒價值的車
	 * 
	 * @see UsedCar.Agent#doAging()
	 */
	public void doAging() {
		long time = System.currentTimeMillis();

		super.doAging();
		// 有車時, 請看 sold()
		if (carL.size() > 0) {
			setMyColor(Color.YELLOW);
		}

		// 清空 carL
		carLByPrice.clear();

		// traverse carL
		Iterator<Car> cit = carL.iterator();
		FasterArrayList<Car> removeCarL = new FasterArrayList<Car>();
		while (cit.hasNext()) {
			Car aCar = cit.next();
			List<Car> rCar = new FasterArrayList<Car>();

			// 車子加一歲
			aCar.doAging();
			// 如果車子已經沒有價了
			if (evaluate(aCar) <= 0) {
				removeCarL.add(aCar);
			} else {
				// 如果還有價
				if (carLByPrice.containsKey(aCar.getEvaledPrice())) {
					rCar = (List<Car>) carLByPrice.get(aCar.getEvaledPrice());
				}
				rCar.add(aCar);
				carLByPrice.put((int) aCar.getEvaledPrice(), rCar);
			}
		}

		carL.removeAll(removeCarL);
		// trashCarL.addAll(removeCarL);

		if (FLAG) {
			time = System.currentTimeMillis() - time;
			if (time > 5)
				System.out.println("Seller::doAging(): " + time + " car size:"
						+ carL.size());
		}
	}

	// ---------------------------------------------------------------------------------------------------------------------------------------------//
	// setter and getter
	// ---------------------------------------------------------------------------------------------------------------------------------------------//

	public double getService_ratio() {
		return service_ratio;
	}

	public void setService_ratio(double service_ratio) {
		this.service_ratio = service_ratio;
	}

	public int getTotal_surplus_value() {
		return total_surplus_value;
	}

	public void setTotal_surplus_value(int total_surplus_value) {
		this.total_surplus_value = total_surplus_value;
	}

}
